/**
  ******************************************************************************
  * @file    gt32f030_gpio.c
  * @author  GT Application Team
  * @version V1.0.0
  * @date    03-January-2025   
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2022 Giantec Semicondutor Inc</center></h2>
  *
  *             http://www.giantec-semi.com/
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/        
#include "gt32f030_gpio.h"  
#include "gt32f030_rcc.h"   

/** @addtogroup GT32F030_StdPeriph_Driver
  * @{
  */

/** @defgroup GPIO 
  * @brief GPIO driver modules
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup GPIO_Private_Functions
  * @{
  */ 

/** @defgroup GPIO_Init Initialization and Configuration functions
 *  @brief    Initialization and Configuration functions 
 *
@verbatim   
 ===============================================================================
              #####  Initialization functions #####
 ===============================================================================
@endverbatim
  * @{
  */

/**
  * @brief  De-initializes the GPIOx peripheral registers to their default reset values.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @retval None
  */
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
//  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  if (GPIOx == GPIOA)
  {
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOA, ENABLE);
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOA, DISABLE);
  }
  else if (GPIOx == GPIOB)
  {
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOB, ENABLE);
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOB, DISABLE);
  }
  else if (GPIOx == GPIOF)
  {
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOF, ENABLE);
    RCC_PeriphResetCmd(RCC_PeriphReset_GPIOF, DISABLE);
  }
}

/**
  * @brief  Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral  
  * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
  *         the configuration information for the specified GPIO peripheral.
  * @retval None
  */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
  uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
  assert_param(IS_GPIO_DIR(GPIO_InitStruct->GPIO_Dir));
  assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
  assert_param(IS_GPIO_DRV(GPIO_InitStruct->GPIO_Drv));
  /* ------------------------- Configure the port pins ---------------- */
  /*-- GPIO Mode Configuration --*/
  for (pinpos = 0x00; pinpos < 0x10; pinpos++)
  {
    pos = ((uint16_t)0x01) << pinpos;
    /* Get the port pins position */
    currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;

    if (currentpin == pos)
    {
      GPIOx->DIR  &= ~(0x1 << (pinpos));
      GPIOx->DIR |= (((uint16_t)GPIO_InitStruct->GPIO_Dir) << (pinpos));

      if (GPIO_InitStruct->GPIO_Dir == GPIO_Dir_OUT)
      {
        /* Check Speed mode parameters */
        assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));

        /* Speed mode configuration */
        GPIOx->SLEWRR &= ~(0x1 << (pinpos ));
        GPIOx->SLEWRR |= ((uint16_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos ));

        /* Check Output mode parameters */
        assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));

        /* Output mode configuration*/
        GPIOx->OUTPUT_TYPE  &= ~((0x1) << ((uint16_t)pinpos)) ;
        GPIOx->OUTPUT_TYPE |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << pinpos);
				

      }
			/*  */
      GPIOx->DRVR &= ~(0x1 << (uint16_t)pinpos );
      GPIOx->DRVR |= (((uint16_t)GPIO_InitStruct->GPIO_Drv) << pinpos );
			
      /* Pull-up Pull down resistor configuration*/
      GPIOx->PUPD &= ~(0x3 << ((uint16_t)pinpos * 2));
      GPIOx->PUPD |= (((uint16_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
    }
  }
}



/**
  * @brief  Fills each GPIO_InitStruct member with its default value.
  * @param  GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized.
  * @retval None
  */
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
{
  /* Reset GPIO init structure parameters values */
  GPIO_InitStruct->GPIO_Pin   = GPIO_Pin_All;
  GPIO_InitStruct->GPIO_Dir   = GPIO_Dir_IN;
  GPIO_InitStruct->GPIO_Speed = GPIO_Speed_Low;
  GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct->GPIO_PuPd  = GPIO_PuPd_NOPULL;
	
}

/**
  * @}
  */


/** @defgroup GPIO_Group2 GPIO Read and Write
 *  @brief   GPIO Read and Write
 *
@verbatim   
 ===============================================================================
                         ##### GPIO Read and Write #####
 ===============================================================================  
@endverbatim
  * @{
  */

/**
  * @brief  Reads the specified input port pin.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..7).
  * @retval The input port pin value.
  */
unsigned int GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  unsigned int bitstatus = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));

  if (GPIOx->INPUT_DATA & GPIO_Pin)
  {
    bitstatus = (unsigned int)Bit_SET;
  }
  else
  {
    bitstatus = (unsigned int)Bit_RESET;
  }
  return bitstatus;
}

/**
  * @brief  Reads the specified GPIO input data port.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @retval GPIO input data port value.
  */
unsigned int GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return ((unsigned int)GPIOx->INPUT_DATA);
}

/**
  * @brief  Reads the specified output data port bit.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..7).
  * @retval The output port pin value.
  */
unsigned int GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  unsigned int bitstatus = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));

  if (GPIOx->OUTPUT_DATA & GPIO_Pin)
  {
    bitstatus = (unsigned int)Bit_SET;
  }
  else
  {
    bitstatus = (unsigned int)Bit_RESET;
  }
  return bitstatus;
}

/**
  * @brief  Reads the specified GPIO output data port.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @retval GPIO output data port value.
  */
unsigned int GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return (GPIOx->OUTPUT_DATA);
}

/**
  * @brief  Sets the selected data port bits.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral. 
  * @param  GPIO_Pin: specifies the port bits to be written.
  *          This parameter can be any combination of GPIO_Pin_x where x can be (0..7).
  * @retval None
  */
void GPIO_SetBits(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->OUTPUT_SET = GPIO_Pin;
}

/**
  * @brief  Clears the selected data port bits.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral. 
  * @param  GPIO_Pin: specifies the port bits to be written.
  *          This parameter can be any combination of GPIO_Pin_x where x can be (0..7).
  * @retval None
  */
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->OUTPUT_CLR = GPIO_Pin;
}

/**
  * @brief  Sets or clears the selected data port bit.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral. 
  * @param  GPIO_Pin: specifies the port bit to be written.
  *          This parameter can be one of GPIO_Pin_x where x can be (0..7).
  * @param  BitVal: specifies the value to be written to the selected bit.
  *          This parameter can be one of the BitAction enum values:
  *            @arg Bit_RESET: to clear the port pin
  *            @arg Bit_SET: to set the port pin
  * @retval None
  */
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin, BitAction BitVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_BIT_ACTION(BitVal));

  if (BitVal != Bit_RESET)
  {
    GPIOx->OUTPUT_SET = GPIO_Pin;
  }
  else
  {
    GPIOx->OUTPUT_CLR = GPIO_Pin ;
  }
}

/**
  * @brief  Writes data to the specified GPIO data port.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral. 
  * @param  PortVal: specifies the value to be written to the port output data register.
  * @retval None
  */
void GPIO_Write(GPIO_TypeDef* GPIOx, unsigned int PortVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  GPIOx->OUTPUT_DATA = PortVal;
}

/**
  * @brief  Toggles the specified GPIO pins..
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral. 
  * @param  GPIO_Pin: Specifies the pins to be toggled.
  * @retval None
  */
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  GPIOx->OUTPUT_TGL = GPIO_Pin;
	//GPIOx->OR ^= GPIO_Pin;
}

/**
  * @}
  */

/** @defgroup GPIO_Group3 GPIO Alternate&Driver functions configuration function
 *  @brief   GPIO Alternate functions configuration function
 *
@verbatim   
 ===============================================================================
           ##### GPIO Alternate&Driver functions configuration function #####
 ===============================================================================  
@endverbatim
  * @{
  */

/**
  * @brief  Changes the Alternate function of the specified pin.
  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral. 
  * @param  GPIO_PinSource: specifies the pin for the Alternate function.
  *         This parameter can be GPIO_PinSourcex where x can be (0..7).
  * @param  GPIO_AF: selects the pin to used as Alternate function.
  * @retval None
  */
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, unsigned int GPIO_PinSource, unsigned int GPIO_AF)
{
  unsigned int temp = 0x00;
  
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  assert_param(IS_GPIO_AF(GPIO_AF));
	
	if(GPIO_PinSource<8)
	{
		temp  =  GPIOx->AFR0;
		temp &= ~(0xf<<(GPIO_PinSource<<2));
		temp |=  (GPIO_AF<<(GPIO_PinSource<<2));
		GPIOx->AFR0  =  temp;	
	}
	else
	{
		GPIO_PinSource = GPIO_PinSource-8;
		temp  =  GPIOx->AFR1;
		temp &= ~(0xf<<(GPIO_PinSource<<2));
		temp |=  (GPIO_AF<<(GPIO_PinSource<<2));
		GPIOx->AFR1  =  temp;	
	}
}


/**
  * @brief  Changes the Driving of the specified pin.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: This parameter can be one of the  values:GPIO_Driving_Strong or GPIO_Driving_Normal.
  * @retval None
  */
void GPIO_PinDriverSelect(GPIO_TypeDef* GPIOx,unsigned int GPIO_Pin,GPIODrv_TypeDef Drv)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
	assert_param(IS_GPIO_DRV(Drv));
	
	if(Drv != GPIO_Drv_Strong)
	{
		GPIOx->DRVR  |= GPIO_Pin;
	}
	else
	{
		GPIOx->DRVR  &= ~GPIO_Pin;
	}
}
/**
  * @}
  */ 

/** @defgroup GPIO_Group4 GPIO Debounce functions configuration
 *  @brief   GPIO Debounce functions configuration
 *
@verbatim   
 ===============================================================================
           ##### GPIO Debounce functions configuration #####
 ===============================================================================  
@endverbatim
  * @{
  */
/**
  * @brief  Enables or disables the specified Port Debounce synchronization.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  NewState: new state of the Debounce synchronization.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void GPIO_DBSyncCmd(GPIO_TypeDef* GPIOx,FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	if(NewState != DISABLE)
	{
		GPIOx->INPUT_DBCR1  |= GPIO_DBCR1_SYNCEN;
	}
	else
	{
		GPIOx->INPUT_DBCR1  &= ~GPIO_DBCR1_SYNCEN;
	}
}

/**
  * @brief  Enables or disables the specified GPIO pin Debounce function.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..15).
  * @param  NewState: new state of the Debounce function.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void GPIO_DBPinCmd(GPIO_TypeDef* GPIOx,unsigned int GPIO_Pin,FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	if(NewState != DISABLE)
	{
		GPIOx->INPUT_DBCR1  |= GPIO_Pin;
	}
	else
	{
		GPIOx->INPUT_DBCR1  &= ~GPIO_Pin;
	}
}

/**
  * @brief  Enables or disables the specified Port Debounce clock source.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  NewState: new state of the Debounce clock source.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void GPIO_DBClkCmd(GPIO_TypeDef* GPIOx,FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	if(NewState != DISABLE)
	{
		GPIOx->INPUT_DBCR2  |= GPIO_DBCR2_CLKEN;
	}
	else
	{
		GPIOx->INPUT_DBCR2  &= ~GPIO_DBCR2_CLKEN;
	}
}
/**
  * @brief  Debounce sample clock source selection for specified Port
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  DBClk: Select the Debounce sample clock
  * @retval None.
  */
void GPIO_DBClkSelect(GPIO_TypeDef* GPIOx,unsigned int DBClk)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx)) ;
	assert_param(IS_GPIO_DBCR2_CYCLE(DBClk));
	/*Set the specified GPIO port DB Clock */
	GPIOx->INPUT_DBCR2  &= ~GPIO_DBCR2_CYCLEMASK;
  GPIOx->INPUT_DBCR2  |= DBClk;
}


/**
  * @}
  */

/** @defgroup GPIO_Group5 GPIO Interrupt functions configuration function
 *  @brief   GPIO Interrupt functions configuration function
 *
@verbatim   
 ===============================================================================
           ##### GPIO Interrupt functions configuration function #####
 ===============================================================================  
@endverbatim
  * @{
  */

/**
  * @brief  Initializes the GPIOx Interrupt according to the specified parameters in the GPIOInt_InitStruct.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral.   
  * @param  GPIOInt_InitStruct: pointer to a GPIOInt_InitTypeDef structure that contains
  *         the configuration information for the specified GPIO Interrupt.
  * @retval None
  */
void GPIOInt_Init(GPIO_TypeDef* GPIOx, GPIOInt_InitTypeDef* GPIOInt_InitStruct)
{
  unsigned int pinpos = 0x00, pos = 0x00 , currentpin = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIOInt_InitStruct->GPIO_Pin));
  assert_param(IS_GPIO_INTTRIGGER(GPIOInt_InitStruct->GPIOInt_Trigger));
	
  /* ------------------------- Configure the port pins ---------------- */
  /*-- GPIO Mode Configuration --*/
  for (pinpos = 0x00; pinpos < 0x10; pinpos++)
  {
    pos = ((uint16_t)0x01) << pinpos;
    /* Get the port pins position */
    currentpin = (GPIOInt_InitStruct->GPIO_Pin) & pos;

    if (currentpin == pos)
    {
			
      GPIOx->INTTYPE &= ~(0x1 << (pinpos));
			GPIOx->INTPOLE &= ~(0x1 << (pinpos));
			GPIOx->INTANY &= ~(0x1 << (pinpos)) ;

			GPIOx->INTPOLE |= (GPIOInt_InitStruct->GPIOInt_Trigger&0x1) << pinpos;	
      GPIOx->INTTYPE |= ((GPIOInt_InitStruct->GPIOInt_Trigger&0x2)>>1) << pinpos;		
			GPIOx->INTANY |= ((GPIOInt_InitStruct->GPIOInt_Trigger&0x4)>>2) << pinpos;
			
			if (GPIOInt_InitStruct->GPIOInt_Cmd != DISABLE)
				GPIOx->INTEN |=  (0x01 << (pinpos));
			else
				GPIOx->INTEN &= ~(0x01 << (pinpos));			
    }
  }
}


/**
  * @}
  */


/** @defgroup GPIO_IntrFlag Interrupts and flags management functions
 *  @brief   Interrupts and flags management functions
 *
@verbatim   
 ===============================================================================
           ##### Interrupts and flags management functions #####
 ===============================================================================  
@endverbatim
  * @{
  */

/**
  * @brief  Get the specified GPIO pin Raw Interrupt flag.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..7).
  * @retval The new Raw Interrupt flag (SET or RESET).
  */
ITStatus GPIO_GetRawIT(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  FlagStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  
  if ((GPIOx->INTRAWSR & GPIO_Pin) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
}



/**
  * @brief  Get the specified GPIO pin Interrupt flag.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..7).
  * @retval The new Interrupt flag (SET or RESET).
  */
ITStatus GPIO_GetIT(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  FlagStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  if ((GPIOx->INTMASKSR & GPIO_Pin) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;  
}


/**
  * @brief  Clear the specified GPIO pin Interrupt and Raw Interrupt flag.
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_Pin_x where x can be (0..7).
  * @retval None
  */
void GPIO_ClearIT(GPIO_TypeDef* GPIOx, unsigned int GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  
  GPIOx->INTCLR = GPIO_Pin;
}
/**
  * @}
  */ 

/**
  * @}
  */

/**
  * @}
  */ 

/**
  * @}
  */ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
